<?php

namespace app\common\service;

use app\common\model\ImageHash;
use think\facade\Cache;
use think\facade\Filesystem;

/**
 * 文件哈希值-服务类
 * @author 小码哥
 * @since: 2023/11/28
 * Class AppletService
 * @package app\admin\service
 */
class ImageHashService extends BaseService
{
    /**
     * 构造函数
     * LevelService constructor.
     */
    public $name = 'hash';

    public function __construct()
    {
        $this->model = new ImageHash();
    }

    /**
     * @param string $form_name
     * @param string $save_dir
     * @param string $error
     * @return array|bool
     * 上传文件
     */
    public function upload_image($form_name = 'file', $save_dir = "", &$error = '')
    {
        // 获取文件对象
        $files = \request()->file($form_name);
        // 判断是否有上传的文件
        if (!$files) {
            $error = "请选择图片";
            return false;
        }
        $save_dir = empty($save_dir) ? 'nxcsoft' : $save_dir;
        try {
            // 允许上传的后缀
            $allowext = 'gif,GIF,jpg,JPG,jpeg,JPEG,png,PNG,bmp,BMP';
            // 上传路径
            if (is_array($files)) {
                $data = [];
                foreach ($files as $file) {
                    $hash = $file->hash('sha1');
                    $imageData = $this->check_file($file, $allowext, $hash);
                    if ($imageData) {
                        $data[] = $imageData;
                        continue;
                    }
                    $savename = $this->save_file($save_dir, $file, $hash);
                    if ($savename) {
                        // 拼接路径
                        $path = str_replace('\\', '/', '/' . $savename);
                        $data[] = [
                            'filepath' => $path,
                            'filename' => $file->getOriginalName(),
                            'fileext' => $file->extension(),
                            'filesize' => $file->getSize(),
                        ];
                    }
                }
                return $data;
            } else {
                $hash = $files->hash('sha1');
                $imageData = $this->check_file($files, $allowext, $hash);
                if ($imageData) {
                    $data = $imageData;
                    return $data;
                }
                $savename = $this->save_file($save_dir, $files, $hash, $files->getSize());
                if ($savename) {
                    // 拼接路径
                    $path = str_replace('\\', '/', '/' . $savename);
                    $data = [
                        'filepath' => $path,
                        'filename' => $files->getOriginalName(),
                        'fileext' => $files->extension(),
                        'filesize' => $files->getSize(),
                    ];
                }
                return $data;
            }
        } catch (ValidateException $e) {
            // 上传校验失败
            $error = $e->getMessage();
        } catch (Exception $e) {
            // 上传异常
            $error = $e->getMessage();
        }
        return false;
    }

    /**
     * 上传单个文件
     * @param string $form_name 文件表单名
     * @param string $save_dir 存储文件夹名
     * @param string $error 错误信息
     * @return array 返回结果
     * @author 小码哥
     * @date 2023/3/28
     */
    public function upload_file($form_name = 'file', $save_dir = "", &$error = '')
    {
        // 获取文件对象
        $files = \request()->file($form_name);
        // 判断是否有上传的文件
        if (!$files) {
            $error = "请选择文件";
            return false;
        }
        try {
            // 允许上传的后缀
            $allowext = 'xls,xlsx,doc,docx,ppt,pptx,zip,rar,mp3,txt,pdf,sql,js,css,chm';
            // 上传路径
            $save_dir = empty($save_dir) ? 'nxcsoft' : $save_dir;
            if (is_array($files)) {
                $data = [];
                foreach ($files as $file) {
                    $imageData = $this->check_file($file, $allowext);
                    if ($imageData) {
                        $data[] = $imageData;
                        continue;
                    }
                    $savename = $this->save_file($save_dir, $files);
                    if ($savename) {
                        // 拼接路径
                        $path = str_replace('\\', '/', '/' . $savename);
                        $data[] = [
                            'fileName' => $file->getOriginalName(),
                            'filePath' => $path,
                        ];
                    }
                }
                return $data;
            } else {
                $imageData = $this->check_file($files, $allowext);
                if ($imageData) {
                    $data = $imageData;
                    return $data;
                }
                $savename = $this->save_file($save_dir, $files);
                if ($savename) {
                    // 拼接路径
                    $path = str_replace('\\', '/', '/' . $savename);
                    $data = [
                        'fileName' => $files->getOriginalName(),
                        'filePath' => $path,
                    ];
                }
                return $data;

            }
        } catch (ValidateException $e) {
            // 上传校验失败
            $error = $e->getMessage();
            return false;
        } catch (Exception $e) {
            // 上传异常
            $error = $e->getMessage();
            return false;
        }
    }

    /**
     *校验文件
     * 判断文件上传是否合法
     */
    public function check_file($file, $allowext, $hash)
    {
        // 使用验证器验证上传的文件
        validate(['file' => [
            // 限制文件大小(单位b)，这里限制为4M
            'filesize' => 10 * 1024 * 1024,
            // 限制文件后缀，多个后缀以英文逗号分割
            'fileExt' => $allowext,
        ]])->check(['file' => $file]);
        $data = [];
        $imageHashService = new  ImageHashService();
        $savename = $imageHashService->getInfoByHash($hash, 'image,hash');
        if ($savename) {
            $path = str_replace('\\', '/', '/' . $savename);
            $data = [
                'filepath' => $path,
                'filename' => $file->getOriginalName(),
                'fileext' => $file->extension(),
                'filesize' => $file->getSize(),
            ];
        }
        return $data;
    }

    /**
     * 保存文件信息
     */
    public function save_file($save_dir, $files, $hash, $size)
    {
        // 上传到本地服务器
        $savename = Filesystem::putFile($save_dir, $files,
            function () use ($files) {
                switch (config('filesystem.upload_filename')) {
                    case 'date':
                        $fileName = date('YmdHis') . rand(1000, 9999);
                        break;
                    // 此项即为：保留原始文件名+日期方式
                    case 'original':
                        $fileName = str_replace('.' . $files->getOriginalExtension(), '', $files->getOriginalName() . date('YmdHis'));
                        break;
                    default:
                        $fileName = uniqid();
                        break;
                }
                return $fileName;
            }
        );
        $path = str_replace('\\', '/', '/' . $savename);
        $imageHashService = new  ImageHashService();
        $image = $this->getBaseUrl() . $path;
        $data = [
            'image' => $image,
            'hash' => $hash,
            'size' => $size,
            'status' => 2,
        ];
        $imageHashService->upInfo($data);
        return $savename;
    }

    /**
     * @return mixed|string
     * 返回baseurl
     */
    private function getBaseUrl()
    {
        $configData = Cache::get('storage');
        $configData = json_decode($configData, true);
        switch ($configData['name']) {
            case 'qiniu':
                $baseUrl = $configData['config']['url'];
                break;
            case 'aliyun':
                $baseUrl = $configData['config']['url'];
                break;
            case 'qcloud':
                $baseUrl = $configData['config']['scheme'] . '://' . $configData['cdn'];
                break;
        }
        return $baseUrl;

    }

    /**
     * 更新图片上传状态
     */
    public function upInfoByImage($image)
    {
        $this->model::where('image', $image)->update(['status' => 1]);
        return true;

    }
}